DROP ROLE IF EXISTS role_bypass_test;
DROP
-- start_ignore
DROP RESOURCE GROUP rg_bypass_test;
DROP
-- end_ignore

--
-- setup
--

CREATE RESOURCE GROUP rg_bypass_test WITH (concurrency=2, cpu_rate_limit=20, memory_limit=20, memory_shared_quota=50);
CREATE
CREATE ROLE role_bypass_test RESOURCE GROUP rg_bypass_test;
CREATE

CREATE OR REPLACE FUNCTION repeatPalloc(int, int) RETURNS int AS '@abs_builddir@/../regress/regress@DLSUFFIX@', 'repeatPalloc' LANGUAGE C READS SQL DATA;
CREATE

CREATE OR REPLACE FUNCTION hold_memory(int, int) RETURNS int AS $$ SELECT * FROM repeatPalloc(1, $2) $$ LANGUAGE sql;
CREATE

CREATE OR REPLACE VIEW eat_memory_on_qd_small AS SELECT hold_memory(0,12);
CREATE

CREATE OR REPLACE VIEW eat_memory_on_qd_large AS SELECT hold_memory(0,100);
CREATE

CREATE OR REPLACE VIEW eat_memory_on_one_slice AS SELECT count(null) FROM gp_dist_random('gp_id') t1 WHERE hold_memory(t1.dbid,4)=0 ;
CREATE

CREATE OR REPLACE VIEW eat_memory_on_slices AS SELECT count(null) FROM gp_dist_random('gp_id') t1, gp_dist_random('gp_id') t2 WHERE hold_memory(t1.dbid,4)=0 AND hold_memory(t2.dbid,4)=0 ;
CREATE

CREATE OR REPLACE FUNCTION round_test(float, integer) RETURNS float AS $$ SELECT round($1 / $2) * $2 $$ LANGUAGE sql;
CREATE

CREATE OR REPLACE VIEW memory_result AS SELECT rsgname, ismaster, round_test(avg(memory_usage), 1) AS avg_mem FROM( SELECT rsgname, CASE (j->'key')::text WHEN '"-1"'::text THEN 1 ELSE 0 END AS ismaster, ((j->'value')->>'used')::int AS memory_usage FROM( SELECT rsgname, row_to_json(json_each(memory_usage::json)) AS j FROM gp_toolkit.gp_resgroup_status WHERE rsgname='rg_bypass_test' )a )b GROUP BY (rsgname, ismaster) ORDER BY rsgname, ismaster;
CREATE

GRANT ALL ON eat_memory_on_qd_small TO role_bypass_test;
GRANT
GRANT ALL ON eat_memory_on_qd_large TO role_bypass_test;
GRANT
GRANT ALL ON eat_memory_on_one_slice TO role_bypass_test;
GRANT
GRANT ALL ON eat_memory_on_slices TO role_bypass_test;
GRANT
GRANT ALL ON memory_result TO role_bypass_test;
GRANT

--
-- SET command should be bypassed
--

ALTER RESOURCE GROUP rg_bypass_test SET concurrency 0;
ALTER
61: SET ROLE role_bypass_test;
SET
61&: SELECT 1;  <waiting ...>
ALTER RESOURCE GROUP rg_bypass_test set concurrency 1;
ALTER
61<:  <... completed>
 ?column? 
----------
 1        
(1 row)
ALTER RESOURCE GROUP rg_bypass_test set concurrency 0;
ALTER
61: SET enable_hashagg to on;
SET
61: SHOW enable_hashagg;
 enable_hashagg 
----------------
 on             
(1 row)
61: invalid_syntax;
ERROR:  syntax error at or near "invalid_syntax"
LINE 1: invalid_syntax;
        ^
61q: ... <quitting>

--
-- gp_resource_group_bypass
--

ALTER RESOURCE GROUP rg_bypass_test SET concurrency 0;
ALTER
61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61: SHOW gp_resource_group_bypass;
 gp_resource_group_bypass 
--------------------------
 on                       
(1 row)
61: CREATE TABLE table_bypass_test (c1 int);
CREATE
61: INSERT INTO  table_bypass_test SELECT generate_series(1,100);
INSERT 100
61: SELECT count(*) FROM table_bypass_test;
 count 
-------
 100   
(1 row)
61: DROP TABLE table_bypass_test;
DROP
61: SET gp_resource_group_bypass to off;
SET
61: SHOW gp_resource_group_bypass;
 gp_resource_group_bypass 
--------------------------
 off                      
(1 row)
61q: ... <quitting>

--
-- gp_resource_group_bypass is not allowed inside a transaction block
--

61: BEGIN;
BEGIN
61: SET gp_resource_group_bypass to on;
ERROR:  SET gp_resource_group_bypass cannot run inside a transaction block
61: ABORT;
ABORT
61q: ... <quitting>

--
-- gp_resource_group_bypass is not allowed inside a function
--

DROP FUNCTION IF EXISTS func_resgroup_bypass_test(int);
DROP
CREATE FUNCTION func_resgroup_bypass_test(c1 int) RETURNS INT AS $$ SET gp_resource_group_bypass TO ON; /* inside a function */ SELECT 1 $$ LANGUAGE SQL;
CREATE
SELECT func_resgroup_bypass_test(1);
ERROR:  SET gp_resource_group_bypass cannot run inside a transaction block
CONTEXT:  SQL function "func_resgroup_bypass_test" statement 1
DROP FUNCTION func_resgroup_bypass_test(int);
DROP


--
-- memory limit in bypass mode, on qd
--

61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61: BEGIN;
BEGIN
61: SELECT * FROM eat_memory_on_qd_small;
 hold_memory 
-------------
 0           
(1 row)
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 12.0    
(2 rows)
61: SELECT * FROM eat_memory_on_qd_large;
ERROR:  Out of memory
DETAIL:  Resource group memory limit reached
CONTEXT:  SQL function "hold_memory" statement 1
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: ABORT;
ABORT
61: BEGIN;
BEGIN
SELECT 1 FROM memory_result where avg_mem > 10 and ismaster = 1;
 ?column? 
----------
 1        
(1 row)
61q: ... <quitting>

--
-- memory limit in bypass mode, on one slice
--

61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61: BEGIN;
BEGIN
61: SELECT * FROM eat_memory_on_one_slice;
 count 
-------
 0     
(1 row)
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 4.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: SELECT * FROM eat_memory_on_one_slice;
 count 
-------
 0     
(1 row)
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 8.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: SELECT * FROM eat_memory_on_one_slice;
ERROR:  Out of memory  (seg0 slice1 127.0.0.1:25432 pid=336)
DETAIL:  Resource group memory limit reached
CONTEXT:  SQL function "hold_memory" statement 1
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: ABORT;
ABORT
61: BEGIN;
BEGIN
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61q: ... <quitting>

--
-- memory limit in bypass mode, on slices
--

61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61: BEGIN;
BEGIN
61: SELECT * FROM eat_memory_on_slices;
 count 
-------
 0     
(1 row)
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 4.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: SELECT * FROM eat_memory_on_slices;
 count 
-------
 0     
(1 row)
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 8.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: SELECT * FROM eat_memory_on_slices;
ERROR:  Out of memory  (seg0 slice2 127.0.0.1:25432 pid=354)
DETAIL:  Resource group memory limit reached
CONTEXT:  SQL function "hold_memory" statement 1
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61: ABORT;
ABORT
61: BEGIN;
BEGIN
SELECT * FROM memory_result;
 rsgname        | ismaster | avg_mem 
----------------+----------+---------
 rg_bypass_test | 0        | 0.0     
 rg_bypass_test | 1        | 0.0     
(2 rows)
61q: ... <quitting>

--
-- gp_resgroup_status.num_running is updated in bypass mode
--

61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61&: SELECT pg_sleep(10);  <waiting ...>
62: SET ROLE role_bypass_test;
SET
62: SET gp_resource_group_bypass to on;
SET
62&: SELECT pg_sleep(20);  <waiting ...>
SELECT num_running FROM gp_toolkit.gp_resgroup_status WHERE rsgname='rg_bypass_test';
 num_running 
-------------
 2           
(1 row)
SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE rsgname='rg_bypass_test';
 pg_cancel_backend 
-------------------
 t                 
 t                 
(2 rows)
61<:  <... completed>
ERROR:  canceling statement due to user request
62<:  <... completed>
ERROR:  canceling statement due to user request
61q: ... <quitting>
62q: ... <quitting>

--
-- pg_stat_activity is updated in bypass mode
--

61: SET ROLE role_bypass_test;
SET
61: SET gp_resource_group_bypass to on;
SET
61&: SELECT pg_sleep(10);  <waiting ...>
62: SET ROLE role_bypass_test;
SET
62: SET gp_resource_group_bypass to on;
SET
62&: SELECT pg_sleep(20);  <waiting ...>
SELECT query FROM pg_stat_activity WHERE rsgname='rg_bypass_test';
 query                
----------------------
 SELECT pg_sleep(20); 
 SELECT pg_sleep(10); 
(2 rows)
SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE rsgname='rg_bypass_test';
 pg_cancel_backend 
-------------------
 t                 
 t                 
(2 rows)
61<:  <... completed>
ERROR:  canceling statement due to user request
62<:  <... completed>
ERROR:  canceling statement due to user request
61q: ... <quitting>
62q: ... <quitting>

--
-- cleanup
--

REVOKE ALL ON eat_memory_on_qd_small FROM role_bypass_test;
REVOKE
REVOKE ALL ON eat_memory_on_qd_large FROM role_bypass_test;
REVOKE
REVOKE ALL ON eat_memory_on_one_slice FROM role_bypass_test;
REVOKE
REVOKE ALL ON eat_memory_on_slices FROM role_bypass_test;
REVOKE
REVOKE ALL ON memory_result FROM role_bypass_test;
REVOKE

DROP ROLE role_bypass_test;
DROP
DROP RESOURCE GROUP rg_bypass_test;
DROP

-- vi:filetype=sql:
